package com.cityfood.controller;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.cityfood.common.utils.HttpClientUtil;

import net.sf.json.JSONObject;
import weixin.popular.bean.xmlmessage.XMLMessage;
import weixin.popular.bean.xmlmessage.XMLTextMessage;
import weixin.popular.support.ExpireKey;
import weixin.popular.support.expirekey.DefaultExpireKey;
import weixin.popular.util.SignatureUtil;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
* 消息接收控制层
* @author YaoShiHang
* @Date 15:15 2017-10-16
*/
@Controller
public class WxqrcodeController {

   private final String TOKEN="cf2019";                      //Wx 开发者设置的 token
   private Logger loger = Logger.getLogger(getClass());
   //重复通知过滤
   private static ExpireKey expireKey = new DefaultExpireKey();


   //微信推送事件 url
   @RequestMapping("/openwx/getticket")
   public void getTicket(HttpServletRequest request, HttpServletResponse response)
           throws Exception {
       ServletInputStream inputStream = request.getInputStream();
       ServletOutputStream outputStream = response.getOutputStream(); 
       String signature = request.getParameter("signature");
       String timestamp = request.getParameter("timestamp");
       String nonce = request.getParameter("nonce");
       String echostr = request.getParameter("echostr");

       //首次请求申请验证,返回echostr
       if(echostr!=null){
           outputStreamWrite(outputStream,echostr);
           return;
       }

       //验证请求签名
       if(!signature.equals(SignatureUtil.generateEventMessageSignature(TOKEN,timestamp,nonce))){
           System.out.println("The request signature is invalid");
           return;
       }

       boolean isreturn= false;
       loger.info("1.收到微信服务器消息");
       Map<String, String> wxdata=parseXml(request);

       if(wxdata.get("MsgType")!=null){
           if("event".equals(wxdata.get("MsgType"))){
               loger.info("2.1解析消息内容为：事件推送");
               if( "subscribe".equals(wxdata.get("Event"))){
                   loger.info("2.2用户第一次关注 返回true哦");
                   isreturn=true;
               }
           }
       }

       if(isreturn == true){
           //转换XML
           String key = wxdata.get("FromUserName")+ "__"
                   + wxdata.get("ToUserName")+ "__"
                   + wxdata.get("MsgId") + "__"
                   + wxdata.get("CreateTime");
           loger.info("3.0 进入回复 转换对象："+key);

           if(expireKey.exists(key)){
               //重复通知不作处理
               loger.info("3.1  重复通知了");
               return;
           }else{
               loger.info("3.1  第一次通知");
               expireKey.add(key);
           }

           loger.info("3.2  回复你好");
           //创建回复
           XMLMessage xmlTextMessage = new XMLTextMessage(
                   wxdata.get("FromUserName"),
                   wxdata.get("ToUserName"),
                   "你好");
           //回复
           xmlTextMessage.outputStreamWrite(outputStream);
           return;
       }
       loger.info("3.2  回复空");
       outputStreamWrite(outputStream,"");
   }

   /**
    * 数据流输出
    * @param outputStream
    * @param text
    * @return
    */
   private boolean outputStreamWrite(OutputStream outputStream, String text){
       try {
           outputStream.write(text.getBytes("utf-8"));
       } catch (UnsupportedEncodingException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
           return false;
       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
           return false;
       }
       return true;
   }

   /**
    * dom4j 解析 xml 转换为 map
    * @param request
    * @return
    * @throws Exception
    */
   public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
       // 将解析结果存储在HashMap中
       Map<String, String> map = new HashMap<String, String>();
       // 从request中取得输入流
       InputStream inputStream = request.getInputStream();
       // 读取输入流
       SAXReader reader = new SAXReader();
       Document document = reader.read(inputStream);
       // 得到xml根元素
       Element root = document.getRootElement();
       // 得到根元素的所有子节点
       List<Element> elementList = root.elements();

       // 遍历所有子节点
       for (Element e : elementList)
           map.put(e.getName(), e.getText());

       // 释放资源
       inputStream.close();
       inputStream = null;
       return map;
   }

   /**
    * 回复微信服务器"文本消息"
    * @param response
    * @param returnvaleue
    */
   public void output(HttpServletResponse response, String returnvaleue) {
       try {
           PrintWriter pw = response.getWriter();
           pw.write(returnvaleue);
           loger.info("****************return valeue***************="+returnvaleue);
           pw.flush();
       } catch (IOException e) {
           e.printStackTrace();
       }
       
       
   }
   
   
   
   /**
	 * 统一服务消息
	 * 小程序模板消息,发送服务通知
	 * @param token 小程序ACCESS_TOKEN
	 * @param touser 用户openid，可以是小程序的openid，也可以是公众号的openid
	 * @param template_id 小程序模板消息模板id
	 * @param page 小程序页面路径
	 * @param formid 小程序模板消息formid
	 * @param data 小程序模板消息formid
	 * @param emphasis_keyword 小程序模板放大关键词
	 * @return
	 * @author HGL
	 */
	public static JSONObject sendWeappMessage(String token,String touser,String template_id,
			String page,String formid,JSONObject data){
		JSONObject obj = new JSONObject();
		JSONObject weapp_template_msg = new JSONObject();
		JSONObject result = new JSONObject();
		try {
			String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="+token;
			obj.put("touser", touser);
			weapp_template_msg.put("template_id", template_id);
			weapp_template_msg.put("page", page);
			weapp_template_msg.put("form_id", formid);
			weapp_template_msg.put("data", data);
			weapp_template_msg.put("emphasis_keyword", data.getJSONObject("keyword1").getString("value"));
			obj.put("weapp_template_msg", weapp_template_msg);
			result = HttpClientUtil.Post(url, obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 统一服务消息
	 * 公众号模板消息,发送公众号通知
	 * @param token 小程序ACCESS_TOKEN
	 * @param touser 用户openid，可以是小程序的openid，也可以是公众号的openid
	 * @param appid 公众号appid
	 * @param template_id 公众号模板消息模板id
	 * @param url 公众号模板消息所要跳转的url
	 * @param weappid 公众号模板消息所要跳转的小程序appid，小程序的必须与公众号具有绑定关系
	 * @param pagepath 公众号模板消息所要跳转的小程序页面
	 * @param data 公众号模板消息的数据
	 * @return
	 * @author HGL
	 */
	public static JSONObject sendMpMessage(String token,String touser,String appid,
			String template_id,String url,String weappid,String pagepath,JSONObject data){
		JSONObject result = new JSONObject();
		JSONObject obj = new JSONObject();
		JSONObject mp_template_msg = new JSONObject();
		JSONObject miniprogram = new JSONObject();
		try {
			String path = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="+token;
			obj.put("touser", touser);
			mp_template_msg.put("appid",appid);
			mp_template_msg.put("template_id", template_id);
			mp_template_msg.put("url",url);
			miniprogram.put("appid", weappid);
			miniprogram.put("pagepath", pagepath);
			mp_template_msg.put("miniprogram", miniprogram);
			mp_template_msg.put("data", data);
			obj.put("mp_template_msg", mp_template_msg);
			result = HttpClientUtil.Post(path, obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
   
   
}